<?php

namespace TpAmis\Traits;

use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use TpAmis\Renderers\AjaxAction;
use TpAmis\Renderers\DialogAction;
use TpAmis\Renderers\OtherAction;
use TpAmis\Renderers\Service;

trait ButtonsTrait
{
    /**
     * 返回列表按钮
     */
    protected function backButton(): OtherAction
    {
        return amis()->OtherAction()
            ->label(admin_trans('admin.back'))
            ->icon('fa-solid fa-chevron-left')
            ->level('primary')
            ->onClick('window.history.back();');
    }

    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function AjaxFormButton(string $title = '', string $url = '', string $method = 'get', array $args = [], array $options = []): AjaxAction
    {
        return $this->AjaxButton($title, $url, $method, $args, $options);

    }

    /**
     * ajax按钮
     * @param string $title
     * @param string $url
     * @param string $method
     * @param array $args
     * @param array $options
     * @return AjaxAction
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function AjaxButton(string $title = '', string $url = '', string $method = 'get', array $args = [], array $options = []): AjaxAction
    {
        $args[$this->primaryKey] = '${' . $this->primaryKey . '}';

        $action = amis()->AjaxAction()->label($title);
        foreach ($options as $key => $option) {
            //添加自定义参数，
            $action->$key($option);
        }

        $action->api($this->BaseApi($url, $method, $args))->level('link');
        if (!authamis($url)) {
            $action->disabled();
        }
        return $action;
    }

    /**
     *  自定义按钮
     * @param string $ActionName
     * @param string $title 弹窗标题 & 按钮文字, 默认: 新增
     * @param array $options
     * @return mixed
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function customButton(string $ActionName = 'AjaxAction', string $title = '', array $options = [])
    {
        $title = $title ?: '自定义';

        $action = amis()->$ActionName()->label($title)->level('link');

        foreach ($options as $key => $option) {
            if (isset($options['url'])) {
                continue;
            }
            //添加自定义参数，
            $action->$key($option);
        }
        if (isset($options['url'])) {
            if (!authamis($options['url'])) {
                $action->disabled();
            }
        }
        return $action;
    }


    /**
     * @param string $url
     * @return DialogAction
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function bulkDeleteButton(string $url = ''): DialogAction
    {
        $action = amis()->DialogAction()
            ->label(admin_trans('删除'))
            ->icon('fa-solid fa-trash-can')
            ->dialog(
                amis()->Dialog()
                    ->title(admin_trans('删除'))
                    ->className('py-2')
                    ->actions([
                        amis()->Action()->actionType('cancel')->label('取消'),
                        amis()->Action()->actionType('submit')->label('删除')->level('danger'),
                    ])
                    ->body([
                        amis()->Form()->wrapWithPanel(false)->api(adminUrl($url))->body([
                            amis()->Tpl()->className('py-2')->tpl('确认删除选中项？'),
                        ]),
                    ])
            );
        if (!authamis(adminUrl($url))) {
            return $action->disabled();
        }
        return $action;
    }


    /**
     * 行编辑按钮
     * @param string $title 弹窗标题 & 按钮文字, 默认: 编辑
     * @param string $dialogSize 弹窗大小, 默认: md, 可选值: xs | sm | md | lg | xl | full
     * @return DialogAction
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function createButton(string $title = '添加', string $dialogSize = 'md'): DialogAction
    {
        $IFrame = amis()->IFrame()->src(adminUrl('create', [$this->primaryKey => '${' . $this->primaryKey . '}'], true, true));
        $action = amis()->DialogAction()->dialog(
            amis()->Dialog()->title($title)->body($IFrame)->size($dialogSize)->actions([])
        );

        $action->label($title)->level('success');
        if (!authamis(adminUrl('create'))) {
            return $action->disabled();
        }
        return $action;
    }

    /**
     * 行编辑按钮
     *
     * @param string $title 弹窗标题 & 按钮文字, 默认: 编辑
     *
     * @param string $dialogSize 弹窗大小, 默认: md, 可选值: xs | sm | md | lg | xl | full
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function rowEditorButton(string $title = '编辑', string $dialogSize = 'md'): DialogAction
    {
        $IFrame = amis()->IFrame()->src(adminUrl('edit', [$this->primaryKey => '${' . $this->primaryKey . '}'], true, true));
        $action = amis()->DialogAction()->dialog(
            amis()->Dialog()->title($title)->body($IFrame)->size($dialogSize)->actions([])
        );

        $action->label($title)->level('link');
        if (!authamis(adminUrl('edit'))) {
            $action->disabled();
        }
        return $action;
    }


    /**
     * 行删除按钮
     *
     * @param string $title
     * @param string $url
     * @return DialogAction
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function rowDeleteButton(string $title = '删除', string $url = 'delete'): DialogAction
    {
        $action = amis()->DialogAction()
            ->label($title)
            ->level('link')
            ->className('text-danger')
            ->dialog(
                amis()->Dialog()
                    ->title()
                    ->className('py-2')
                    ->actions([
                        amis()->Action()->actionType('cancel')->label('取消'),
                        amis()->Action()->actionType('submit')->label('删除')->level('danger'),
                    ])
                    ->body([
                        amis()->Form()->wrapWithPanel(false)->api($this->BaseApiDelete(adminUrl($url, [$this->primaryKey => '${' . $this->primaryKey . '}'], true, true)))
                            ->body([
                                amis()->Tpl()->className('py-2')->tpl('确认删除'),
                            ]),
                    ])
            );
        if (!authamis(adminUrl('delete'))) {
            return $action->disabled(true);
        }
        return $action;
    }


    protected string $exportApi = 'export';


    /**
     * 行启用按钮
     *
     * @param string $title
     * @param string $method
     * @param array $args
     * @param array $options
     * @return AjaxAction
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function rowEnableButton(string $title = '启用', string $method = 'post', array $args = [], array $options = []): AjaxAction
    {
        return $this->rowStatusButton($title, 'enable', $method, $args, $options);

    }


    /**
     * 行禁用按钮
     *
     * @param string $title
     * @param string $method
     * @param array $args
     * @param array $options
     * @return AjaxAction
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function rowDisableButton(string $title = '禁用', string $method = 'post', array $args = [], array $options = []): AjaxAction
    {

        return $this->rowStatusButton($title, 'disable', $method, $args, $options);
    }


    /**
     * 行状态开关按钮
     *
     * @param string $title
     * @param string $url
     * @param string $method
     * @param array $args
     * @param array $options
     * @return AjaxAction
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function rowStatusButton(string $title = '', string $url = 'status', string $method = 'post', array $args = [], array $options = []): AjaxAction
    {
        isset($args[$this->primaryKey]) ?: $args[$this->primaryKey] = '${' . $this->primaryKey . '}';
        $action = $this->AjaxButton($title, $url, $method, $args, $options)->level('link');
        if (!authamis($url)) {
            $action->disabled();
        }
        return $action;
    }

    /**
     * 导出按钮
     *
     * @param bool $disableSelectedItem
     * @param string $url
     * @return Service
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function exportAction(bool $disableSelectedItem = false, string $url = ''): Service
    {

        // 下载路径
        $downloadPath = adminUrl('_download_export');
        // 导出接口地址
        $exportPath = $this->BaseApiPost($url ?: $this->exportApi);
        // 无数据提示
        $pageNoData = '本页无数据';
        // 选中行无数据提示
        $selectedNoData = '请选择要导出的数据';
        // 按钮点击事件
        // $event = fn($script) => ['click' => ['actions' => [['actionType' => 'custom', 'script' => $script]]]];
        $event = function ($script) {
            return [
                'click' => [
                    'actions' => [
                        ['actionType' => 'custom', 'script' => $script]
                    ]
                ]
            ];
        };
        // 导出处理动作
        $doAction = "doAction([{actionType:'setValue',componentId:'export-action',args:{value:{showExportLoading:true}}},{actionType:'ajax',args:{api:{url:url.toString(),method:'get'}}},{actionType:'setValue',componentId:'export-action',args:{value:{showExportLoading:false}}},{actionType:'custom',expression:'\${event.data.responseResult.responseStatus===0}',script:'window.open(\'{$downloadPath}?path=\'+event.data.responseResult.responseData.path)'}])";
        // 按钮
        $buttons = [
            // 导出全部
            amis()->VanillaAction()->label(admin_trans('admin.export.all'))->onEvent(
                $event("let data=event.data;let params=Object.keys(data).filter(key=>key!=='page' && key!=='__super').reduce((obj,key)=>{obj[key]=data[key];return obj;},{});let url=new URL('{$exportPath}',window.location.origin);Object.keys(params).forEach(key=>url.searchParams.append(key,params[key]));{$doAction}")
            ),
            // 导出本页
            amis()->VanillaAction()->label(admin_trans('admin.export.page'))->onEvent(
                $event("let ids=event.data.items.map(item=>item.{$this->primaryKey});if(ids.length===0){return doAction({actionType:'toast',args:{msgType:'warning',msg:'{$pageNoData}'}})};let url=new URL('{$exportPath}',window.location.origin);url.searchParams.append('_ids',ids.join(','));{$doAction}")
            ),
        ];
        // 导出选中项
        if (!$disableSelectedItem) {
            $buttons[] = amis()->VanillaAction()->label(admin_trans('admin.export.selected_rows'))->onEvent(
                $event("let ids=event.data.selectedItems.map(item=>item.{$this->primaryKey});if(ids.length===0){return doAction({actionType:'toast',args:{msgType:'warning',msg:'{$selectedNoData}'}})};let url=new URL('{$exportPath}',window.location.origin);url.searchParams.append('_ids',ids.join(','));{$doAction}")
            );
        }

        $action = amis()->Service()
            ->id('export-action')
            ->set('align', 'right')
            ->set('data', ['showExportLoading' => false])
            ->body(
                amis()->Spinner()->set('showOn', '${showExportLoading}')->overlay()->body(
                    amis()->DropdownButton()
                        ->label(admin_trans('admin.export.title'))
                        ->set('icon', 'fa-solid fa-download')
                        ->buttons($buttons)
                        ->closeOnClick()
                        ->align('right')
                )
            );
        if (!authamis($exportPath)) {
            return $action->disabled(true);
        }
        return $action;
    }
}